%include "pm.inc"

%ifdef DOS_DEBUG
org 0100h
%else
org 07c00h
%endif

jmp LABEL_BEGIN

[SECTION .gdt]
LABEL_GDT: Descriptor 0, 0, 0
LABEL_DESC_CODE32: dq 0x409a007d500083
LABEL_DESC_VIDEO: Descriptor 0B8000h, 0ffffh, DA_DRW

GdtLen equ $ - LABEL_GDT
GdtPtr dw GdtLen - 1
    dd 0x00007c04
SelectorCode32 equ LABEL_DESC_CODE32 - LABEL_GDT
SelectorVideo equ LABEL_DESC_VIDEO - LABEL_GDT

[SECTION .idt]
ALIGN 32
[BITS 32]
LABEL_IDT:
%rep 32
	Gate SelectorCode32, SpuriousHandler, 0, DA_386IGate
%endrep
.020h: Gate SelectorCode32, ClockHandler, 0, DA_386IGate

IdtLen equ $ - LABEL_IDT
IdtPtr dw IdtLen - 1
	dd 0x00007c40

[SECTION .s32]
[BITS 32]
LABEL_SEG_CODE32:	
	mov ax, SelectorVideo
	mov gs, ax
	
	call Init8259A
	int 05h
	sti
	jmp $
	
Init8259A:
	; 设置主片和从片的ICW1
	mov al, 011h
	out 020h, al
	call io_delay
	
	out 0A0h, al
	call io_delay
	
	; 设置主片和从片的ICW2
	; 20h（32）代表IRQ0~IRQ7的中断向量号是20h~27h
	mov al, 020h
	out 021h, al
	call io_delay
	
	; 28h（40）代表IRQ8~IRQ15的中断向量号是28h~2Fh
	mov al, 028h
	out 0A1h, al
	call io_delay
	
	; 设置主片的ICW3,004表示IR2对应从片
	mov al, 004h
	out 021h, al
	call io_delay
	
	; 设置从片的ICW3,002表示从片连主片的IR号是2
	mov al, 002h
	out 0A1h, al
	call io_delay
	
	; 设置主片的ICW4,1表示sequential模式、正常EOI，80x86模式
	mov al, 001h
	out 021h, al
	call io_delay
	
	; 设置从片的ICW4,1表示sequential模式、正常EOI，80x86模式
	out 0A1h, al
	call io_delay
	
	; 以下设置OCW1
	mov al, 11111110b ; 仅开启定时器中断
	out 021h, al
	call io_delay
	
	mov al, 11111111b
	out 0A1h, al
	call io_delay
	
	ret
	
io_delay:
	nop
	nop
	nop
	nop
	ret
	
_SpuriousHandler:
SpuriousHandler equ _SpuriousHandler - $$
	mov	ah, 0Ch				; 0000: 黑底    1100: 红字
	mov	al, '!'
	mov	[gs:((80 * 0 + 75) * 2)], ax	; 屏幕第 0 行, 第 75 列。
	iretd
	
_ClockHandler:
ClockHandler equ _ClockHandler - $$
	inc	byte [gs:((80 * 0 + 70) * 2)]	; 屏幕第 0 行, 第 70 列。
	mov	al, 20h
	out	20h, al				; 发送 EOI
	iretd
	

SegCode32Len equ $ - LABEL_SEG_CODE32

[SECTION .s16]
[BITS 16]
LABEL_BEGIN:
	mov ax, cs
	mov ds, ax
	mov es, ax

	lgdt [GdtPtr]

	;cli
	
	lidt [IdtPtr]

	in al, 92h
	or al, 00000010b
	out 92h, al

	mov eax, cr0
	or eax, 1
	mov cr0, eax

	jmp dword SelectorCode32:0